﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml.Linq;

namespace Growatt.DuiHelpers
{
    public static class DuiHelperFile
    {
        /// <summary>
        /// 获取目录下的所有文件(包括子目录)
        /// </summary>
        /// <param name="dir">目录路径</param>
        public static List<string> GetAllFile(string dir)
        {
            //获取目录下所有文件
            var fileGroup = Directory.GetFiles(dir).ToList();

            //获取子文件下的所有文件
            var subFileGroup = Directory.GetDirectories(dir).SelectMany(GetAllFile);
            fileGroup.AddRange(subFileGroup);

            return fileGroup;
        }

        /// <summary>
        /// 将文件转换成byte[]数组
        /// </summary>
        /// <param name="fileUrl">文件路径文件名称</param>
        /// <returns>byte[]数组</returns>
        public static byte[] FileToByte(string fileUrl)
        {
            try
            {
                using (FileStream fs = new FileStream(fileUrl, FileMode.Open, FileAccess.Read))
                {
                    byte[] byteArray = new byte[fs.Length];
                    fs.Read(byteArray, 0, byteArray.Length);
                    return byteArray;
                }
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 生成Bin文件
        /// </summary>
        /// <param name="byteArray"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static bool ByteToFileAppend(byte[] byteArray, string fileName)
        {
            bool result = false;
            try
            {
                using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                {
                    fs.Write(byteArray, 0, byteArray.Length);
                    result = true;
                }
            }
            catch
            {
                result = false;
            }
            return result;
        }

        /// <summary>
        /// 加载读取
        /// </summary>
        /// <returns></returns>

        public static string LoadFile(string strPath = null)
        {
            string Result = string.Empty;

            try
            {
                if (!string.IsNullOrEmpty(strPath))
                    if (File.Exists(strPath))
                    {
                        Result = File.ReadAllText(strPath);
                    }
            }
            catch (Exception ex)
            {
                DuiHelperLog.WriteErrorLog(ex);
            }
            finally
            {
            }
            return Result;
        }

        /// <summary>
        /// 以只读、共享方式获取文件内容
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string GetFileTextWithShare(string path)
        {
            //读取文件信息
            using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var strReader = new StreamReader(stream, Encoding.Default))
                {
                    var text = strReader.ReadToEnd();
                    return text;
                }
            }
        }

        /// <summary>获取程序启动路径</summary>
        /// <returns></returns>
        public static string GetStartupPath()
        {
            return System.AppDomain.CurrentDomain.BaseDirectory;
        }

        /// <summary>删除文件</summary>
        /// <param name="strFilePath"></param>
        public static void DeleteFile(string strFilePath)
        {
            if (!File.Exists(strFilePath))
                return;
            File.Delete(strFilePath);
        }

        /// <summary>删除文件夹</summary>
        /// <param name="strFoloderPath"></param>
        public static void DeleteFolder(string strFoloderPath)
        {
            if (!Directory.Exists(strFoloderPath))
                return;
            Directory.Delete(strFoloderPath, true);
        }

        /// <summary>获取文件数据</summary>
        /// <param name="strFilePath"></param>
        /// <returns></returns>
        public static byte[] GetFileData(string strFilePath)
        {
            if (!File.Exists(strFilePath))
                return (byte[])null;
            byte[] buffer;
            using (FileStream fileStream = File.Open(strFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                int int32 = Convert.ToInt32(fileStream.Length);
                buffer = new byte[int32];
                fileStream.Read(buffer, 0, int32);
            }
            return buffer;
        }

        /// <summary>获取目录下的文件数</summary>
        /// <param name="strDirectory"></param>
        /// <returns></returns>
        public static int GetFilesCount(string strDirectory)
        {
            int num = 0;
            if (Directory.Exists(strDirectory))
            {
                string[] files = Directory.GetFiles(strDirectory);
                if (files != null)
                    num = files.Length;
            }
            return num;
        }

        private static object LogSyncLock = new object();

        /// <summary>
        /// 错误信息
        /// </summary>
        public static string ErrorMessage { get; set; }

        /// <summary>保存数据</summary>
        /// <param name="byData"></param>
        /// <param name="strFilePathName"></param>
        /// <returns></returns>
        public static bool SaveFile(byte[] byData, string strFilePathName)
        {
            bool b = false;
            ErrorMessage = null;
            if (byData == null || byData.Length <= 0 || string.IsNullOrEmpty(strFilePathName))
                return false;
            if (CheckAndCreatePath(strFilePathName))
                try
                {
                    lock (LogSyncLock)
                    {
                        File.WriteAllBytes(strFilePathName, byData);
                        b = true;
                    }
                }
                catch (Exception ex)
                {
                    ErrorMessage = ex.Message;
                    Growatt.DuiHelpers.DuiHelperLog.WriteErrorLog(ex);
                }
            return b;
        }

        /// <summary>保存数据</summary>
        /// <param name="byData"></param>
        /// <param name="strFilePathName"></param>
        /// <returns></returns>
        public static bool SaveFile(string strContent, string strFilePathName)
        {
            bool b = false;
            ErrorMessage = null;
            if (strContent == null || strContent.Length <= 0 || string.IsNullOrEmpty(strFilePathName))
                return false;
            if (CheckAndCreatePath(strFilePathName))
                try
                {
                    lock (LogSyncLock)
                    {
                        File.WriteAllText(strFilePathName, strContent);

                        b = true;
                    }
                }
                catch (Exception ex)
                {
                    ErrorMessage = ex.Message;
                    Growatt.DuiHelpers.DuiHelperLog.WriteErrorLog(ex);
                }
            return b;
        }

        public static bool SaveAppendFile(string strContent, string strFilePathName)
        {
            bool b = false;
            ErrorMessage = null;
            if (strContent == null || strContent.Length <= 0 || string.IsNullOrEmpty(strFilePathName))
                return false;
            if (CheckAndCreatePath(strFilePathName))
                try
                {
                    lock (LogSyncLock)
                    {
                        File.AppendAllText(strFilePathName, strContent);
                        b = true;
                    }
                }
                catch (Exception ex)
                {
                    ErrorMessage = ex.Message;
                    Growatt.DuiHelpers.DuiHelperLog.WriteErrorLog(ex);
                }
            return b;
        }

        /// <summary>
        /// 检查并创建目录
        /// </summary>
        /// <param name="strFilePathName"></param>
        public static bool CheckAndCreatePath(string strFilePathName)
        {
            bool b = false;
            ErrorMessage = null;
            try
            {
                if (strFilePathName.Contains("/"))
                    strFilePathName = strFilePathName.Replace("/", "\\");
                string str = strFilePathName.Substring(strFilePathName.LastIndexOf("\\"));
                string path = strFilePathName.Substring(0, strFilePathName.Length - str.Length);
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);
                b = true;
            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message;
                Growatt.DuiHelpers.DuiHelperLog.WriteErrorLog(ex);
            }

            return b;
        }

        public static bool CheckFileIsExist(string path)
        {
            var result = File.Exists(path);
            return result;
        }

        /// <summary>
        /// 检查并创建目录
        /// </summary>
        /// <param name="strFilePathName"></param>
        public static bool CheckAndDeletePath(string strFilePathName)
        {
            bool b = false;
            ErrorMessage = null;
            try
            {
                if (strFilePathName.Contains("/"))
                    strFilePathName = strFilePathName.Replace("/", "\\");
                string str = strFilePathName.Substring(strFilePathName.LastIndexOf("\\"));
                string path = strFilePathName.Substring(0, strFilePathName.Length - str.Length);
                if (Directory.Exists(path))
                    Directory.Delete(path);
                b = true;
            }
            catch (Exception ex)
            {
                ErrorMessage = ex.Message;
                Growatt.DuiHelpers.DuiHelperLog.WriteErrorLog(ex);
            }

            return b;
        }

        public static bool CreateDir(string path)
        {
            if (!Directory.Exists(path))
                Directory.CreateDirectory(path);

            return Directory.Exists(path);
        }

        public static IEnumerable<string> LoadFilelistString(string FileToRead)
        {
            IEnumerable<string> line = null;
            // Creating enumerable object
            if (File.Exists(FileToRead))
                line = File.ReadLines(FileToRead, Encoding.GetEncoding("GB2312"));
            return line;
        }

        /// <summary>
        /// 追加文件内容
        /// </summary>
        /// <param name="strContent"></param>
        /// <param name="strFilePathName"></param>
        /// <returns></returns>
        public static bool AppendFile(string strContent, string strFilePathName)
        {
            bool b = false;
            ErrorMessage = null;
            try
            {
                lock (LogSyncLock)
                {
                    using (FileStream fs = new FileStream(strFilePathName, FileMode.Append))
                    {
                        using (StreamWriter sw = new StreamWriter(fs, Encoding.Default))
                        {
                            sw.WriteLine(strContent);
                            b = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Growatt.DuiHelpers.DuiHelperLog.WriteErrorLog(ex);
            }
            return b;
        }

        ///// <summary>获取配置文件中设置的值</summary>
        ///// <param name="strKey"></param>
        ///// <returns></returns>
        //public static string GetSetValueByAppConfig(string strKey)
        //{
        //    string str = string.Empty;
        //    System.Configuration.Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        //    if (((IEnumerable<string>)ConfigurationManager.AppSettings.AllKeys).Contains<string>(strKey))
        //        str = configuration.AppSettings.Settings[strKey].Value;
        //    return str;
        //}

        /// <summary>移动文件</summary>
        /// <param name="oldFilePath"></param>
        /// <param name="newFilePath"></param>
        public static void MoveFile(string oldFilePath, string newFilePath)
        {
            if (oldFilePath == newFilePath || !File.Exists(oldFilePath) || File.Exists(newFilePath))
                return;
            File.Move(oldFilePath, newFilePath);
        }

        /// <summary>实现从一个目录下完整拷贝到另一个目录下</summary>
        /// <param name="fromDirectory"></param>
        /// <param name="toDirectory"></param>
        public static void CopyFiles(string fromDirectory, string toDirectory)
        {
            Directory.CreateDirectory(toDirectory);
            if (!Directory.Exists(fromDirectory))
                return;
            string[] directories = Directory.GetDirectories(fromDirectory);
            if (directories.Length > 0)
            {
                foreach (string fromDirectory1 in directories)
                {
                    string str = fromDirectory1.Substring(fromDirectory1.LastIndexOf("\\"));
                    CopyFiles(fromDirectory1, toDirectory + str);
                }
            }
            string[] files = Directory.GetFiles(fromDirectory);
            if (files.Length <= 0)
                return;
            foreach (string sourceFileName in files)
                File.Copy(sourceFileName, toDirectory + sourceFileName.Substring(sourceFileName.LastIndexOf("\\")), true);
        }

        /// <summary>拷贝文件</summary>
        /// <param name="fromFilePath"></param>
        /// <param name="toFilePath"></param>
        public static void CopyFile(string fromFilePath, string toFilePath)
        {
            if (string.IsNullOrEmpty(toFilePath) || string.IsNullOrEmpty(fromFilePath) || !File.Exists(fromFilePath))
                return;
            File.Copy(fromFilePath, toFilePath, true);
        }

        ///// <summary>修改配置文件</summary>
        ///// <param name="key"></param>
        ///// <param name="newValue"></param>
        //public static void UpdateAppConfig(string key, string newValue)
        //{
        //    System.Configuration.Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        //    if (((IEnumerable<string>)ConfigurationManager.AppSettings.AllKeys).Contains<string>(key))
        //        configuration.AppSettings.Settings.Remove(key);
        //    configuration.AppSettings.Settings.Add(key, newValue);
        //    configuration.Save(ConfigurationSaveMode.Modified);
        //    ConfigurationManager.RefreshSection("appSettings");
        //}

        /// <summary>获取XML文件</summary>
        /// <param name="xmlFilePath"></param>
        /// <returns></returns>
        public static XDocument GetXMLDocument(string xmlFilePath)
        {
            XDocument xdocument = null;
            if (File.Exists(xmlFilePath))
            {
                StreamReader streamReader = new StreamReader(xmlFilePath);
                StringBuilder stringBuilder = new StringBuilder();
                for (string str = streamReader.ReadLine(); str != null; str = streamReader.ReadLine())
                    stringBuilder.Append(str);
                streamReader.Close();
                streamReader.Dispose();
                if (stringBuilder.Length > 0)
                    xdocument = XDocument.Parse(stringBuilder.ToString());
            }
            return xdocument;
        }

        /// <summary>获取文件的MD5值</summary>
        /// <param name="file"></param>
        /// <param name="fileSize"></param>
        /// <returns></returns>
        public static string GetFileMd5(object file, out long fileSize)
        {
            fileSize = 0L;
            FileInfo fileInfo1 = (FileInfo)null;
            FileInfo fileInfo2 = !(file is FileInfo) ? new FileInfo(string.Concat(file)) : file as FileInfo;
            if (!fileInfo2.Exists)
                return (string)null;
            string str = string.Empty;
            FileStream fileStream = (FileStream)null;
            MD5CryptoServiceProvider cryptoServiceProvider = (MD5CryptoServiceProvider)null;
            try
            {
                fileStream = fileInfo2.OpenRead();
                cryptoServiceProvider = new MD5CryptoServiceProvider();
                str = BitConverter.ToString(cryptoServiceProvider.ComputeHash((Stream)fileStream));
                fileSize = fileStream.Length;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                    fileStream.Dispose();
                }
                if (cryptoServiceProvider != null)
                    cryptoServiceProvider.Dispose();
                if (fileInfo2 != null)
                    fileInfo1 = (FileInfo)null;
            }
            return str;
        }

        public static FileSystemWatcher watcher = new FileSystemWatcher();

        public static Dictionary<string, string> GetAllFileMessage(string filePath)
        {
            Dictionary<string, string> dicFileInfo = new Dictionary<string, string>
            {
                { "获取文件的全路径", Path.GetFullPath(filePath) },
                { "获取文件所在的目录", Path.GetDirectoryName(filePath) },
                { "获取文件的名称含有后缀", Path.GetFileName(filePath) },
                { "获取文件的名称没有后缀", Path.GetFileNameWithoutExtension(filePath) },
                { "获取路径的后缀扩展名称", Path.GetExtension(filePath) },
                { "获取路径的根目录", Path.GetExtension(filePath) }
            };
            return dicFileInfo;
        }

        public static void Start(string path)
        {
            WatcherStart(path, "*.ini", true, true);
        }

        /// <summary>
        /// 初始化监听
        /// </summary>
        /// <param name="StrWarcherPath">需要监听的目录</param>
        /// <param name="FilterType">需要监听的文件类型(筛选器字符串)</param>
        /// <param name="IsEnableRaising">是否启用监听</param>
        /// <param name="IsInclude">是否监听子目录</param>
        private static void WatcherStart(string StrWarcherPath, string FilterType, bool IsEnableRaising, bool IsInclude)
        {
            //初始化监听
            watcher.BeginInit();
            //设置监听文件类型
            watcher.Filter = FilterType;
            //设置是否监听子目录
            watcher.IncludeSubdirectories = IsInclude;
            //设置是否启用监听?
            watcher.EnableRaisingEvents = IsEnableRaising;
            //设置需要监听的更改类型(如:文件或者文件夹的属性,文件或者文件夹的创建时间;NotifyFilters枚举的内容)
            watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
            //设置监听的路径
            watcher.Path = StrWarcherPath;

            ////注册创建文件或目录时的监听事件
            //watcher.Created += new FileSystemEventHandler(watch_created);
            ////注册当指定目录的文件或者目录发生改变的时候的监听事件
            //watcher.Changed += watch_changed;
            ////注册当删除目录的文件或者目录的时候的监听事件
            //watcher.Deleted += watch_deleted;
            ////当指定目录的文件或者目录发生重命名的时候的监听事件
            //watcher.Renamed += watch_renamed;
            //结束初始化
            watcher.EndInit();
        }

        ///// <summary>安全获取图片对象</summary>
        ///// <param name="filePath"></param>
        ///// <returns></returns>
        //public static BitmapImage GetBitmapImage(string filePath)
        //{
        //    BitmapImage bitmapImage = new BitmapImage();
        //    using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
        //    {
        //        bitmapImage.BeginInit();
        //        bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
        //        bitmapImage.StreamSource = (Stream)fileStream;
        //        bitmapImage.EndInit();
        //    }
        //    return bitmapImage;
        //}


        public static bool WriteBatFile(string filePath, string fileContent)
        {
            try
            {
                if (File.Exists(filePath))
                    File.Delete(filePath);
                FileStream fs1 = new FileStream(filePath, FileMode.Create, FileAccess.Write);//创建写入文件
                StreamWriter sw = new StreamWriter(fs1, Encoding.GetEncoding("GB2312"));
                sw.WriteLine(fileContent);//开始写入值
                sw.Close();
                fs1.Close();
                return true;
            }
            catch (Exception ex)
            {
                DuiHelperLog.WriteErrorLog(ex);
                return false;
            }
        }

        public static bool WriteBatFileutf(string filePath, string fileContent)
        {
            try
            {
                if (File.Exists(filePath))
                    File.Delete(filePath);
                FileStream fs1 = new FileStream(filePath, FileMode.Create, FileAccess.Write);//创建写入文件
                StreamWriter sw = new StreamWriter(fs1, Encoding.UTF8);
                sw.WriteLine(fileContent);//开始写入值
                sw.Close();
                fs1.Close();
                return true;
            }
            catch (Exception ex)
            {
                DuiHelperLog.WriteErrorLog(ex);
                return false;
            }
        }

    }
}